package com.template.utils.redis;

import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.stereotype.Component;

import java.util.*;

@Component
public class SetOps extends KeyOps {

    private final SetOperations<String, Object> setOperations;

    public SetOps(RedisTemplate<String, Object> redisTemplate) {
        super(redisTemplate);
        this.setOperations = redisTemplate.opsForSet();
    }


    /**
     * <h4> Set </h4>
     * 添加一个或多个元素
     * <li> sadd _key _value1 _value2 ... </li>
     */
    public Long sAdd(String key, Object... values) {
        return setOperations.add(key, values);
    }

    /**
     * <h4> Set </h4>
     * 添加一个或多个元素
     * <li> sadd _key _value1 _value2 ... </li>
     */
    public Long sAdd(String key, Collection<Object> values) {
        return setOperations.add(key, values.toArray());
    }

    /**
     * <h4> Set </h4>
     * 随机删除并返回一个元素
     * <li> spop _key </li>
     */
    public Object sPop(String key) {
        return setOperations.pop(key);
    }

    /**
     * <h4> Set </h4>
     * 随机删除并返回多个元素
     * <li> spop _key _count </li>
     */
    public List<Object> sPop(String key, int count) {
        return setOperations.pop(key, count);
    }

    /**
     * <h4> Set </h4>
     * 删除一个或多个指定元素
     * <li> srem _key _value1 _value2 ... </li>
     *
     * @return 成功删除个数
     */
    public Long sRem(String key, Object... values) {
        return setOperations.remove(key, values);
    }

    /**
     * <h4> Set </h4>
     * 删除一个或多个指定元素
     * <li> srem _key _value1 _value2 ... </li>
     *
     * @return 成功删除个数
     */
    public Long sRem(String key, Collection<Object> values) {
        return setOperations.remove(key, values.toArray());
    }

    /**
     * <h4> Set </h4>
     * 获取所有元素
     * <li> smembers _key </li>
     */
    public Set<Object> sMembers(String key) {
        return setOperations.members(key);
    }

    /**
     * <h4> Set </h4>
     * 随机获取一个元素
     * <li> srandmember _key </li>
     */
    public Object sRandMember(String key) {
        return setOperations.randomMember(key);
    }

    /**
     * <h4> Set </h4>
     * 随机获取多个元素，不会出现重复
     * <li> srandmember _key _count( + ) </li>
     */
    public Set<Object> sRandMemberSet(String key, long count) {
        return setOperations.distinctRandomMembers(key, count);
    }

    /**
     * <h4> Set </h4>
     * 随机获取多个元素，可能出现重复，数量等于 count
     * <li> srandmember _key _count( - ) </li>
     */
    public List<Object> sRandMemberList(String key, long count) {
        return setOperations.randomMembers(key, count);
    }

    /**
     * <h4> Set </h4>
     * 获取元素个数
     * <li> scard _key </li>
     */
    public Long sCard(String key) {
        return setOperations.size(key);
    }

    /**
     * <h4> Set </h4>
     * 判断 value 是否存在
     * <li> sismember _key _value </li>
     */
    public Boolean sIsMember(String key, Object value) {
        return setOperations.isMember(key, value);
    }

    /**
     * <h4> Set </h4>
     * 批量判断 values 是否存在
     * <li> sismember _key _value1 _value2 ... </li>
     */
    public Map<Object, Boolean> sIsMember(String key, Object... values) {
        return setOperations.isMember(key, values);
    }

    /**
     * <h4> Set </h4>
     * 获取指定 key 的并集
     * <li> sunion _key1 _key2 ... </li>
     */
    public Set<Object> sUnion(String... keys) {
        return setOperations.union(Arrays.asList(keys));
    }

    /**
     * <h4> Set </h4>
     * 获取指定 key 的并集
     * <li> sunion _key1 _key2 ... </li>
     */
    public Set<Object> sUnion(Collection<String> keys) {
        return setOperations.union(keys);
    }

    /**
     * <h4> Set </h4>
     * 将指定 key 的并集存储在 newKey 中
     * <li> sunionstore _newKey _key1 _key2 </li>
     */
    public Long sUnionStore(String newKey, String key1, String key2) {
        return setOperations.unionAndStore(key1, key2, newKey);
    }

    /**
     * <h4> Set </h4>
     * 将指定 key 的并集存储在 newKey 中
     * <li> sunionstore _newKey _key1 _key2 </li>
     */
    public Long sUnionStore(String newKey, Collection<String> keys) {
        return setOperations.unionAndStore(keys, newKey);
    }

    /**
     * <h4> Set </h4>
     * 获取指定 key 的交集
     * <li> sinter _key1 _key2 ... </li>
     */
    public Set<Object> sInter(String... keys) {
        return setOperations.intersect(Arrays.asList(keys));
    }

    /**
     * <h4> Set </h4>
     * 获取指定 key 的交集
     * <li> sinter _key1 _key2 ... </li>
     */
    public Set<Object> sInter(Collection<String> keys) {
        return setOperations.intersect(keys);
    }

    /**
     * <h4> Set </h4>
     * 将指定 key 的交集存储在 newKey 中
     * <li> sinterstore _newKey _key1 _key2 </li>
     */
    public Long sInterStore(String newKey, String key1, String key2) {
        return setOperations.intersectAndStore(key1, key2, newKey);
    }

    /**
     * <h4> Set </h4>
     * 将指定 key 的交集存储在 newKey 中
     * <li> sinterstore _newKey _key1 _key2 ... </li>
     */
    public Long sInterStore(String newKey, Collection<String> keys) {
        return setOperations.intersectAndStore(keys, newKey);
    }

    /**
     * <h4> Set </h4>
     * 获取指定 key 的差集
     * <li> sdiff _key1 _key2 ... </li>
     */
    public Set<Object> sDiff(String... keys) {
        return setOperations.difference(Arrays.asList(keys));
    }

    /**
     * <h4> Set </h4>
     * 获取指定 key 的差集
     * <li> sdiff _key1 _key2 ... </li>
     */
    public Set<Object> sDiff(Collection<String> keys) {
        return setOperations.difference(keys);
    }

    /**
     * <h4> Set </h4>
     * 将指定 key 的差集存储在 newKey 中
     * <li> sdiffstore _newKey _key1 _key2 </li>
     */
    public Long sDiffStore(String newKey, String key1, String key2) {
        return setOperations.differenceAndStore(key1, key2, newKey);
    }

    /**
     * <h4> Set </h4>
     * 将指定 key 的差集存储在 newKey 中
     * <li> sdiffstore _newKey _key1 _key2 ... </li>
     */
    public Long sDiffStore(String newKey, Collection<String> keys) {
        return setOperations.differenceAndStore(keys, newKey);
    }

    /**
     * <h4> Set </h4>
     * 将 value 从 fromKey 中 转移到 toKey
     * <li> smove _formKey _toKey _value </li>
     */
    public Boolean sMove(String formKey, String toKey, Object value) {
        return setOperations.move(formKey, value, toKey);
    }

    /**
     * <h4> Set </h4>
     * 迭代 set 值
     * <li> smove _formKey _toKey _value </li>
     */
    public Cursor<Object> sScan(String key, ScanOptions options) {
        return setOperations.scan(key, options);
    }


}
